﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SharePointLogBrowser2
{
    public class LogItemContext
    {
        private static LogItemContext _Current;
        public static LogItemContext Current
        {
            get
            {
                if (_Current == null)
                {
                    _Current = new LogItemContext();
                }
                return _Current;
            }
        }

        private LogItemCollection _items;
        public LogItemCollection Items
        {
            get { return _items; }
        }

        public void ReadAll(string path)
        {
            LogReader reader = new LogReader();
            _items = reader.ReadAll(path);
        }

        public void ReadAll(List<FileInfo> list)
        {
            LogReader reader = new LogReader();
            _items = reader.ReadAll(list);
        }

        private FilterItemCollection _TextFilters = new FilterItemCollection();
        public FilterItemCollection TextFilters
        {
            get { return _TextFilters; }
        }

        public void AddTextFilter(string textFilter)
        {
            FilterItem item = new FilterItem(textFilter);

            _TextFilters.Add(item);
        }

        private bool ContainsTextFilter(LogItem item)
        {
            if (_TextFilters.Count == 0)
            {
                return false;
            }
            foreach (FilterItem textFilter in TextFilters)
            {
                if (item.Message.StartsWith(textFilter.Text))
                {
                    return true;
                }
            }
            return false;
        }

        internal void LoadTextFilters(string path)
        {
            _TextFilters = new FilterItemCollection();

            StreamReader sr = null;
            try
            {
                sr = File.OpenText(path);

                if (!sr.EndOfStream)
                {
                    while (!sr.EndOfStream)
                    {
                        string line = sr.ReadLine();

                        FilterItem item = new FilterItem(line);
                        TextFilters.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (sr != null)
                {
                    sr.Close();
                }
            }

        }

        internal void SaveTextFilters(string path)
        {
            StreamWriter sr = null;
            try
            {
                sr = new StreamWriter(path, false);
                foreach (FilterItem textFilter in TextFilters)
                {
                    sr.WriteLine(textFilter.Text);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (sr != null)
                {
                    sr.Close();
                }
            }
        }

        internal LogItemCollection FilterByCorrelation(string correlation)
        {
            LogItemCollection items = new LogItemCollection();

            foreach (LogItem item in Items)
            {
                if (item.Correlation == correlation)
                {
                    items.Add(item);
                }
            }

            return items;
        }

        internal void ClearLogItems()
        {
            _items = new LogItemCollection();
        }

        FilterItemCollection _ItemsByProcess = new FilterItemCollection();
        internal FilterItemCollection FilterItemsByProcess()
        {
            return FilterItems(_ItemsByProcess, c => c.Process);
        }

        private FilterItemCollection _ItemsByArea = new FilterItemCollection();
        internal FilterItemCollection FilterItemsByArea()
        {
            return FilterItems(_ItemsByArea, c => c.Area);
        }

        private FilterItemCollection _ItemsByLevel = new FilterItemCollection();
        internal FilterItemCollection FilterItemsByLevel()
        {
            return FilterItems(_ItemsByLevel, c => c.Level);
        }

        private FilterItemCollection _ItemsByCategory = new FilterItemCollection();
        internal FilterItemCollection FilterItemsByCategory()
        {
            return FilterItems(_ItemsByCategory, c => c.Category);
        }

        
        private FilterItemCollection FilterItems(FilterItemCollection items, GetTextFromLogItem getText)
        {
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            foreach (FilterItem filterItem in items)
            {
                dictionary.Add(filterItem.Text, filterItem.Text);
            }

            foreach (LogItem item in Items)
            {
                string text = getText(item);
                if (!string.IsNullOrEmpty(text))
                {
                    if (!dictionary.ContainsKey(text))
                    {
                        dictionary.Add(text, text);
                        FilterItem filterItem = new FilterItem(text);
                        items.Add(filterItem);
                    }
                }
            }

            return items;
        }


        public LogItemCollection Filter()
        {
            LogItemCollection items = new LogItemCollection();

            foreach (LogItem item in Items)
            {
                if (!ContainsTextFilter(item))
                {
                    items.Add(item);
                }
            }

            return items;
        }


        public LogItemCollection Filter(
            bool filterByTextItems,
            bool filterByOthers,
            FilterItemDictionary getFilterItemByArea,
            FilterItemDictionary getFilterItemByCategory,
            FilterItemDictionary getFilterItemByLevel,
            FilterItemDictionary getFilterItemByProcess)
        {
            LogItemCollection items = new LogItemCollection();

            foreach (LogItem item in Items)
            {
                if ((!filterByTextItems
                     || !ContainsTextFilter(item))
                    && (!filterByOthers
                    || (getFilterItemByArea.ContainsText(item.Area)
                    && getFilterItemByCategory.ContainsText(item.Category)
                    && getFilterItemByLevel.ContainsText(item.Level)
                    && getFilterItemByProcess.ContainsText(item.Process))))
                {
                    items.Add(item);
                }
            }

            return items;
        }
    }
}
